import NodeRSA from 'node-rsa';

class RSAEncryption {
  constructor(options = {}) {
    // 设置默认参数
    this.defaultKeySize = options.defaultKeySize || 1024;
    this.defaultPublicExponent = options.defaultPublicExponent || '010001';
    this.enableLogging = options.log || false;
    this.key = null;
    this.publicKey = null;
  }

  // 设置公钥
  setPublicKey(publicKeyString) {
    try {
      this.publicKey = new NodeRSA(publicKeyString, 'public');
      this.publicKey.setOptions({
        encryptionScheme: 'pkcs1', // 使用 PKCS1 填充方案
      });

      if (this.enableLogging) {
        console.log('Public key set successfully');
      }
    } catch (error) {
      console.error('Error setting public key:', error.message);
      throw error;
    }
  }

  // 设置私钥
  setPrivateKey(privateKeyString) {
    try {
      this.key = new NodeRSA(privateKeyString, 'private');
      this.key.setOptions({
        encryptionScheme: 'pkcs1',
        signingScheme: 'pkcs1',
      });

      if (this.enableLogging) {
        console.log('Private key set successfully');
      }
    } catch (error) {
      console.error('Error setting private key:', error.message);
      throw error;
    }
  }

  // 加密方法 - 这是生成 payToken 的核心方法
  encrypt(plainText) {
    try {
      if (!this.publicKey) {
        throw new Error(
          'Public key not set. Please call setPublicKey() first.'
        );
      }

      // 将输入转换为字符串（如果不是的话）
      const textToEncrypt = String(plainText);

      // 使用公钥加密
      const encryptedData = this.publicKey.encrypt(textToEncrypt, 'base64');

        if (this.enableLogging) {
          console.log('Encryption successful');
          console.log('Input:', textToEncrypt);
          console.log('Output (base64):', encryptedData);
        }

      return encryptedData;
    } catch (error) {
      console.error('Encryption error:', error.message);
      return false;
    }
  }

  // 解密方法
  decrypt(encryptedData) {
    try {
      if (!this.key) {
        throw new Error(
          'Private key not set. Please call setPrivateKey() first.'
        );
      }

      const decryptedData = this.key.decrypt(encryptedData, 'utf8');

      if (this.enableLogging) {
        console.log('Decryption successful');
        console.log('Input:', encryptedData);
        console.log('Output:', decryptedData);
      }

      return decryptedData;
    } catch (error) {
      console.error('Decryption error:', error.message);
      return false;
    }
  }

  // 签名方法
  sign(data, hashAlgorithm = 'sha256') {
    try {
      if (!this.key) {
        throw new Error(
          'Private key not set. Please call setPrivateKey() first.'
        );
      }

      const signature = this.key.sign(data, hashAlgorithm, 'base64');

      if (this.enableLogging) {
        console.log('Signing successful');
        console.log('Data:', data);
        console.log('Signature:', signature);
      }

      return signature;
    } catch (error) {
      console.error('Signing error:', error.message);
      return false;
    }
  }

  // 验证签名
  verify(data, signature, hashAlgorithm = 'sha256') {
    try {
      if (!this.publicKey) {
        throw new Error(
          'Public key not set. Please call setPublicKey() first.'
        );
      }

      const isValid = this.publicKey.verify(
        data,
        signature,
        hashAlgorithm,
        'utf8'
      );

      if (this.enableLogging) {
        console.log('Verification result:', isValid);
        console.log('Data:', data);
        console.log('Signature:', signature);
      }

      return isValid;
    } catch (error) {
      console.error('Verification error:', error.message);
      return false;
    }
  }

  // 生成新的密钥对
  generateKeyPair(keySize = this.defaultKeySize) {
    try {
      const newKey = new NodeRSA({ b: keySize });
      newKey.setOptions({
        encryptionScheme: 'pkcs1',
        signingScheme: 'pkcs1',
      });

      this.key = newKey;

      if (this.enableLogging) {
        console.log(`Generated new key pair with size: ${keySize}`);
      }

      return {
        privateKey: newKey.exportKey('private'),
        publicKey: newKey.exportKey('public'),
      };
    } catch (error) {
      console.error('Key generation error:', error.message);
      return false;
    }
  }

  // 获取公钥
  getPublicKey() {
    if (this.publicKey) {
      return this.publicKey.exportKey('public');
    }
    return null;
  }

  // 获取私钥
  getPrivateKey() {
    if (this.key) {
      return this.key.exportKey('private');
    }
    return null;
  }

  // 获取公钥（Base64格式）
  getPublicKeyB64() {
    if (this.publicKey) {
      return this.publicKey.exportKey('public');
    }
    return null;
  }

  // 获取私钥（Base64格式）
  getPrivateKeyB64() {
    if (this.key) {
      return this.key.exportKey('private');
    }
    return null;
  }
}

// 凤凰小程序加密
export function generatePayToken(inputText, enableLogging = false) {
  try {
    // 创建 RSA 加密实例
    const rsa = new RSAEncryption({ log: enableLogging });

    // 设置公钥（这是你提供的公钥）
    const publicKey =
      'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkBrjQbx41mxBK9Ft7s6+yYy6G8kGhQ87sDYjjQXXfngR0pwbkpF19htS04Grhi6/ufGiSReIAGF9yPgcOIziVAPFzvy0/bIlB2PA32mbCBnQTTOVg3UJsHSxoWizucp7ght6dfWAeP5iGUWldb5XgwdlHMySqCo7eAK+qLOd+2GaOkuF1MvZvrXWwXKfHQYBQKPoRbGMeTDY7ZphWw5AVl5dP1kNMsOGS1k/w81DLcx1LdhTkdLYSDxbPp7SZVNSmp3MnCdpV5gzaDZAiNyDJewTIM8/1Avl+iCIBDtxMlZLklBcsLm4TN9FW6I5K10vIqxWH5EadETGQib148xUFwIDAQAB';

    rsa.setPublicKey(publicKey);

    // 加密输入文本，生成 payToken
    const payToken = rsa.encrypt(inputText);

    if (payToken === false) {
      throw new Error('Encryption failed');
    }

    return payToken;
  } catch (error) {
    console.error('Error generating payToken:', error.message);
    return null;
  }
}

// 导出模块
// module.exports = {
//   RSAEncryption,
//   generatePayToken,
// };

// 如果直接运行此文件，则执行测试
// if (require.main === module) {
//   testEncryption();
// }
